<?php

namespace App\Services;

use Closure;
use EasyWeChat\Pay\Application;
use Exception;
use Illuminate\Support\Facades\Log;
use EasyWeChat\Pay\Message;

class WechatService extends BaseService
{
    /**
     * 微信支付
     */
    public function payment($param = [])
    {
        $appid = config('services.wechat.appid');
        $mchid = config('services.wechat.mch_id');
        $config = $this->payConfig();

        $app = new Application($config);
        $response = $app->getClient()->postJson("v3/pay/transactions/jsapi",
            array_merge([
                "appid" => $appid, // <---- 请修改为服务号的 appid
                "mchid" => $mchid, // <---- 请修改为您的商户号
                "out_trade_no" => "native12177525012012070352333'.rand(1,1000).'",
                "description" => "Image形象店-深圳腾大-QQ公仔",
                "notify_url" => "https://weixin.qq.com/",
                "amount" => [
                    "total" => 1,
                    "currency" => "CNY"
                ],
                "payer" => [
                    "openid" => "o4GgauInH_RCEdvrrNGrnxxxxxx" // <---- 请修改为服务号下单用户的 openid
                ]
            ], $param))->toArray(false);

        if (isset($response['code'])) {
            $this->throwBusinessException($response['message']);
        }
        $prepayId = $response['prepay_id'];
        $utils = $app->getUtils();
        $signType = 'RSA'; // 默认RSA，v2要传MD5
        $config = $utils->buildBridgeConfig($prepayId, $appid, $signType); // 返回数组

        return $config;
    }

    /**
     * 支付回调
     */
    public function payNotify()
    {
        try {
            $config = $this->payConfig();
            $app = new Application($config);

            $server = $app->getServer();

            $server->handlePaid(function (Message $message, Closure $next) {
                if ($message->trade_state === 'SUCCESS') {
                    Log::info('支付成功通知', $message->toArray());
                    OrderService::getInstance()->notify($message->toArray());
                }
                return $next($message);
            });

            $response = $server->serve();
            return response($response->getBody(), 200, $response->getHeaders());

        } catch (Exception $e) {
            Log::warning('支付异步通知处理失败', [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
                'message' => $e->getMessage(),
            ]);

            // 返回统一错误响应，防止暴露细节
            $this->throwBusinessException('支付失败');
        }
    }

    /**
     * 退款
     */
    public function refund($param = [])
    {
        $config = $this->payConfig();

        $app = new Application($config);
        $response = $app->getClient()->postJson("/v3/refund/domestic/refunds",
            array_merge([
                "transaction_id" => "1217752501201407033233368018'.rand(1,1000).'",
                "out_trade_no" => "1217752501201407033233368018'.rand(1,1000).'",
                "out_refund_no" => "1217752501201407033233368018'.rand(1,1000).'",
                "reason" => "商品已售完",
                "notify_url" => "https://weixin.qq.com/",
//                "funds_account" => "AVAILABLE",
                "amount" => [
                    "refund" => 888,
//                    "from" => [
//                        [
//                            "account" => "AVAILABLE",
//                            "amount" => 444
//                        ]
//                    ],
                    "total" => 888,
                    "currency" => "CNY"
                ],
//                "goods_detail" => [
//                    [
//                        "merchant_goods_id" => "1217752501201407033233368018",
//                        "wechatpay_goods_id" => "1001",
//                        "goods_name" => "iPhone6s 16G",
//                        "unit_price" => 528800,
//                        "refund_amount" => 528800,
//                        "refund_quantity" => 1,
//                    ]
//                ]
            ], $param))->toArray(false);

        if (isset($response['code'])) {
            throw new Exception($response['message']);
        }
        Log::info('微信退款成功通知', $response);
        if ($response['status'] == 'SUCCESS') {
            throw new Exception('退款已成功');
        } elseif ($response['status'] == 'CLOSED') {
            throw new Exception('退款已关闭');
        } elseif ($response['status'] == 'ABNORMAL') {
            throw new Exception('退款异常，前往商户平台-交易中心，手动处理此笔退款');
        } else {
            return $response;
        }
    }

    /**
     * 退款回调
     */
    public function refundNotify()
    {
        try {
            $config = $this->payConfig();
            $app = new Application($config);

            $server = $app->getServer();

            $server->handleRefunded(function (Message $message, Closure $next) {
                if ($message->refund_status === 'SUCCESS') {
                    Log::info('退款成功通知', $message->toArray());
                    RefundService::getInstance()->notify($message->toArray());
                }
                return $next($message);
            });

            $response = $server->serve();
            return response($response->getBody(), 200, $response->getHeaders());

        } catch (Exception $e) {
            Log::warning('退款异步通知处理失败', [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
                'message' => $e->getMessage(),
            ]);

            // 返回统一错误响应，防止暴露细节
            $this->throwBusinessException('退款失败');
        }
    }

    /**
     * 支付配置
     */
    private function payConfig()
    {
        $config = [
            "appid" => config('services.wechat.appid'),
            'mch_id' => config('services.wechat.mch_id'),
            // 商户证书
            'private_key' => storage_path('wechat/apiclient_key.pem'),
            'certificate' => storage_path('wechat/apiclient_cert.pem'),

            // v3 API 秘钥
            'secret_key' => '5MrPlKKFSAcvvgPyyp72h8kerlil1an9',

            // v2 API 秘钥
            'v2_secret_key' => '5MrPlKKFSAcvvgPyyp72h8kerlil1an9',

            // 平台证书：微信支付 APIv3 平台证书，需要使用工具下载
            // 下载工具：https://github.com/wechatpay-apiv3/CertificateDownloader
            'platform_certs' => [
                // 如果是「平台证书」模式
                // 使用 Key/Value 结构， key 为 平台证书的序列号，value 为微信支付平台证书的绝对路径
                "{7506A7BA4B27E5AE4966CC2C4B57760D74BF4EAE}" => storage_path('wechat/wechatpay_38227E46D0ED555A3630AF1B8A7F24329A621EAE.pem')

                // 如果是「微信支付公钥」模式
                // 使用 Key/Value 结构， key 为微信支付公钥 ID(PUB_KEY_ID 开头)，value 为微信支付公钥文件绝对路径
                // "{$pubKeyId}" => '/path/to/wechatpay/pubkey.pem',
            ],

            /**
             * 接口请求相关配置，超时时间等，具体可用参数请参考：
             * https://github.com/symfony/symfony/blob/5.3/src/Symfony/Contracts/HttpClient/HttpClientInterface.php
             */
            'http' => [
                'throw' => true, // 状态码非 200、300 时是否抛出异常，默认为开启
                'timeout' => 5.0,
                // 如果你在国外想要覆盖默认的 url 的时候才使用，根据不同的模块配置不同的 base_uri
                // 'base_uri' => 'https://api.mch.weixin.qq.com/',
            ],
        ];

        return $config;
    }
}
